package org.codefinger.dao.callback;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.codefinger.dao.callback.PojoListQueryCallback.AttrItemSetter;
import org.codefinger.dao.impl.ResultSetCallback;
import org.codefinger.dao.util.jdbc.JDBCUtil;
import org.codefinger.dao.util.magic.MagicAttribute;
import org.codefinger.dao.util.magic.MagicConstructor;
import org.codefinger.dao.util.magic.MagicPojo;

public class PojoSetQueryCallback<T> implements ResultSetCallback<Set<T>> {

	private MagicConstructor<T>	constructor;

	private AttrItemSetter[]	attrItemSetters;

	public PojoSetQueryCallback(Class<T> pojoClass, String[] aliases) {
		super();
		MagicPojo<T> magicPojo = MagicPojo.getMagicPojo(pojoClass);
		int length = aliases.length;
		List<AttrItemSetter> attrItemSetters = new ArrayList<AttrItemSetter>(length);
		MagicAttribute magicAttribute;
		int index = 0;
		for (String alias : aliases) {
			index++;
			magicAttribute = magicPojo.getMagicAttribute(alias);
			if (magicAttribute == null) {
				magicAttribute = magicPojo.getMagicAttributeByUpperCase(alias.toUpperCase());
			}
			if (magicAttribute == null) {
				continue;
			}
			attrItemSetters.add(new AttrItemSetter(magicAttribute, JDBCUtil.getRSGetter(magicAttribute.getField().getType()), index));
		}
		this.constructor = magicPojo.getConstructor();
		this.attrItemSetters = attrItemSetters.toArray(new AttrItemSetter[attrItemSetters.size()]);
	}

	@Override
	public Set<T> getResult(ResultSet resultSet, String[] aliases) throws SQLException {
		AttrItemSetter[] attrItemSetters = this.attrItemSetters;
		MagicConstructor<T> constructor = this.constructor;
		Set<T> set = new HashSet<T>();
		T pojo;
		while (resultSet.next()) {
			pojo = constructor.newInstance();
			for (AttrItemSetter attrItemSetter : attrItemSetters) {
				attrItemSetter.setValue(pojo, resultSet);
			}
			set.add(pojo);
		}
		return set;
	}

}
